
package com.skcc.cop.mrtaxi.biz;


import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.location.LocationClient;
import com.skcc.cop.mrtaxi.BaseActivity;
import com.skcc.cop.mrtaxi.R;
import com.skcc.cop.mrtaxi.biz.appinfo.AppInfoActivity;
import com.skcc.cop.mrtaxi.biz.destination.ManageDestinationActivity;
import com.skcc.cop.mrtaxi.biz.faq.FaqActivity;
import com.skcc.cop.mrtaxi.biz.history.CallHistoryActivity;
import com.skcc.cop.mrtaxi.http.CallListener;
import com.skcc.cop.mrtaxi.http.GetDriverListListener;
import com.skcc.cop.mrtaxi.http.model.Driver;
import com.skcc.cop.mrtaxi.util.Dialogs;
import com.skcc.cop.mrtaxi.util.Dialogs.DialogListener;
import com.skcc.cop.mrtaxi.util.LocationUtils;
import com.skcc.cop.mrtaxi.util.LogControl;
import com.skcc.cop.mrtaxi.view.TitleBar2;
import com.skcc.cop.mrtaxi.view.TitleBar2.OnTitleBarEventListener2;


public class HomeListActivity extends BaseActivity implements 
	OnTitleBarEventListener2,
	GooglePlayServicesClient.ConnectionCallbacks,
	GooglePlayServicesClient.OnConnectionFailedListener {

	// ===========================================================
	// Constants
	// ===========================================================
	private static final String TAG = HomeListActivity.class.getSimpleName();
	
	
	// ===========================================================
	// Fields
	// ===========================================================
	private TitleBar2 mTitleBarView;
	
	private DrawerLayout mDrawerLayout;
	private View mMenu;
	
	// TODO: ImageView 로 변경할 것.
	private TextView mDestinationTextview;
	private TextView mCallhistoryTextview;
	private TextView mFaqTextview;
	private TextView mAppinfoTextview;
	
	private ListView mDriverList;
	private DriverListAdapter mAdapter;
	private List<Driver> driverList = new ArrayList<Driver> ();
	
	// Stores the current instantiation of the location client in this object
    private LocationClient mLocationClient;
    private int distanceId;

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_home_list);
		
		Intent intent = getIntent();   // 값을 받기 위한 Intent 생성
		distanceId = intent.getIntExtra("distance", 0);
		
		mTitleBarView = (TitleBar2) this.findViewById(R.id.titlebar_view);
		mTitleBarView.setEventListener(this);
		mTitleBarView.showMenu();
		mTitleBarView.showMoveMap();
		mTitleBarView.setTitle(R.string.title);
		
		mDriverList = (ListView) this.findViewById(R.id.home_driverlist_listview);
		mDriverList.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
				Driver item = (Driver) driverList.get(position);
//				Dialogs.showDialogDriverInfo(HomeListActivity.this, item, dialogListener2);
//				Dialogs.showDialogDriverInfo(HomeMapActivity.this, d, dialogListener2);
				Intent intent = new Intent(HomeListActivity.this, CallRequestActivity.class);
				Bundle bundle = new Bundle();
				Location currentLocation = mLocationClient.getLastLocation();
				double userLatitude = currentLocation.getLatitude();
				double userLongitude = currentLocation.getLongitude();
				bundle.putString("imgUrl", item.getImgUrl());
				bundle.putString("driverName", item.getName());
				bundle.putString("carNumber", item.getCarNumber());
				bundle.putString("companyName", item.getCompany());
				bundle.putString("driverPhoneNumber", item.getPhoneNumber());
				bundle.putInt("distance", item.getDistance());
				bundle.putDouble("userLatitude", userLatitude);
				bundle.putDouble("userLongitude", userLongitude);
				intent.putExtra("driver", bundle);
				
				SharedPreferences.Editor editor = getSharedPreferences("driverSharedPref",MODE_PRIVATE).edit();
				editor.putString("imgUrl", item.getImgUrl());
				editor.putString("driverName", item.getName());
				editor.putString("carNumber", item.getCarNumber());
				editor.putString("companyName", item.getCompany());
				editor.putString("driverPhoneNumber", item.getPhoneNumber());
				editor.putInt("distance", item.getDistance());
				editor.putFloat("userLatitude", (float)userLatitude);
				editor.putFloat("userLongitude", (float)userLongitude);
				editor.commit();
				startActivity(intent);
			}
		});
		
		mAdapter = new DriverListAdapter(HomeListActivity.this, R.layout.view_driver_list_item, driverList);
		mDriverList.setAdapter(mAdapter);
		
		mDrawerLayout = (DrawerLayout) this.findViewById(R.id.drawer_layout);
		mDrawerLayout.setDrawerListener(new AppDrawerListener());
		mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
		
		mMenu = this.findViewById(R.id.home_menu_layout);
		mDestinationTextview = (TextView) this.findViewById(R.id.menu_destination_textview);
		mCallhistoryTextview = (TextView) this.findViewById(R.id.menu_callhistory_textview);
		mFaqTextview = (TextView) this.findViewById(R.id.menu_faq_textview);
		mAppinfoTextview = (TextView) this.findViewById(R.id.menu_appinfo_textview);
		
		mMenu.setOnClickListener(clickListener);
		mDestinationTextview.setOnClickListener(clickListener);
		mCallhistoryTextview.setOnClickListener(clickListener);
		mFaqTextview.setOnClickListener(clickListener);
		mAppinfoTextview.setOnClickListener(clickListener);
		
		// Create a new location client, using the enclosing class to handle callbacks.
        mLocationClient = new LocationClient(this, this, this);
	}
	
	 // Called when the Activity becomes visible.
    @Override
    protected void onStart() {
        super.onStart();
        
        // Connect the client.
        mLocationClient.connect();
    }

	@Override
	protected void onResume() {
		super.onResume();
		LogControl.d(TAG, " in onResume >>>>>");
	}
	
	@Override
	protected void onPause() {
		super.onPause();
		LogControl.d(TAG, " in onPause >>>>>");
	}
	
	// Called when the Activity is no longer visible.
    @Override
    protected void onStop() {
        // Disconnecting the client invalidates it.
        mLocationClient.disconnect();
        
        super.onStop();
    }

	@Override
	protected void onDestroy() {
		LogControl.d(TAG, " in onDestroy >>>>>");
		super.onDestroy();
	}

	@Override
	public void onBackPressed() {
		Dialogs.showDialogYesNo(HomeListActivity.this, getString(R.string.confirm_finish), new DialogListener() {

			@Override
			public void onClickedOk() {
				finish();
			}

			@Override
			public void onClickedCancel() {
				Dialogs.dismiss();
			}
		});
	}

	@Override
	public void onMenuClicked() {
		openDrawer();
	}
	
	@Override
	public void onMoveMapClicked() {
		Intent intent = new Intent(HomeListActivity.this, HomeMapActivity.class);
		startActivity(intent);
		finish();
	}
	
	@Override
	public void onConnectionFailed(ConnectionResult connectionResult) {
		/*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
            try {

                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(
                        this,
                        LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST);

                /*
                * Thrown if Google Play services canceled the original PendingIntent
                */

            } catch (IntentSender.SendIntentException e) {

                // Log the error
                e.printStackTrace();
            }
        } else {

            // If no resolution is available, display a dialog to the user with the error.
            showErrorDialog(connectionResult.getErrorCode());
        }
	}

	@Override
	public void onConnected(Bundle arg0) {
		if (servicesConnected()) {
			// Get the current location
			try{
				
				
				
				Location currentLocation = mLocationClient.getLastLocation();
				
				
				Log.i(TAG, ""+mLocationClient.isConnected());
				//Log.i(TAG, ""+mLocationClient.getErrorCode(this));
				//Log.i(TAG, ""+ mLocationClient.getLastLocation().);
				
				
				if( mLocationClient.getLastLocation() == null || mLocationClient.isConnected() == false){
					
					Toast.makeText(HomeListActivity.this, "현재위치  불러오기 실패 ", Toast.LENGTH_LONG).show();
					
				}else{
					
		            if(distanceId == 0) {
		            	getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude());
						Toast.makeText(HomeListActivity.this, "전체 driver show", Toast.LENGTH_LONG).show();
					} else if(distanceId == 1) {
						getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 1);
						Toast.makeText(HomeListActivity.this, "1km 이내 driver show", Toast.LENGTH_LONG).show();
					} else if(distanceId == 2) {
						getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 3);
						Toast.makeText(HomeListActivity.this, "3km 이내 driver show", Toast.LENGTH_LONG).show();
					} else if (distanceId == 3) {
						getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 5);
						Toast.makeText(HomeListActivity.this, "5km 이내 driver show", Toast.LENGTH_LONG).show();
					} else {
						getTaxiDriverList(mLocationClient.getLastLocation().getLatitude(), mLocationClient.getLastLocation().getLongitude(), 10);
						Toast.makeText(HomeListActivity.this, "10km 이내 driver show", Toast.LENGTH_LONG).show();
					}
				}
			}catch (NullPointerException e){
				
				Toast.makeText(HomeListActivity.this, "알수 없는 에러가 발생하였습니다.(NullPointException)", Toast.LENGTH_LONG).show();
				e.printStackTrace();
			}
			
		}
	}

	@Override
	public void onDisconnected() {
		// TODO Auto-generated method stub
		mLocationClient.disconnect();
	}

	// @Override
	// public boolean onCreateOptionsMenu(Menu menu) {
	// // Inflate the menu; this adds items to the action bar if it is present.
	// getMenuInflater().inflate(R.menu.main, menu);
	// return true;
	// }
	// ===========================================================
	// Methods
	// ===========================================================
	private OnClickListener clickListener = new OnClickListener() {
		
		@Override
		public void onClick(View v) {
			if(v.getId() == R.id.menu_destination_textview) {
				Log.i(TAG, ">>>>>>>>>>>> menu_destination_textview");
				moveManageDestination();
			} else if(v.getId() == R.id.menu_callhistory_textview) {
				Intent intent = new Intent(HomeListActivity.this, CallHistoryActivity.class);
		        startActivity(intent);
			} else if(v.getId() == R.id.menu_faq_textview) {
				Intent intentFaq = new Intent(HomeListActivity.this, FaqActivity.class);
		        startActivity(intentFaq);
			} else if(v.getId() == R.id.menu_appinfo_textview) {
				Intent intentAppInfo = new Intent(HomeListActivity.this, AppInfoActivity.class);
		        startActivity(intentAppInfo);
			} /*else if(v.getId() == R.id.home_opendestination_button) {
				Log.i(TAG, ">>>>>>>>>>>> openConfig_button");
				moveManageDestination();
			} */
			
			return;
		}
	};
	
	private void openDrawer() {
		mDrawerLayout.openDrawer(Gravity.LEFT);
	}
	
	private void moveManageDestination() {
		Intent intent = new Intent(HomeListActivity.this, ManageDestinationActivity.class);
        startActivity(intent);
	}
	
	
//	// TODO: 콜 요청 전문 보내기
//	// 1. 선택된 목적지 정보를 보내야 한다.
//	// 2. 고객 정보를 보내야 한다.
//	// 3. 인터페이스 문서보고 메소드 명/전문명 수정할 것.
//	private void requestCall() {
//		showProgressDialog(this, R.string.loading);
//		
//		String tempDriverId = "TempDriverId";
//		String tempUserId = "TempUserId";
////		gateway.call(tempDriverId, tempUserId, new CallListener() {
////
////			@Override
////			public void onNoNetwork() {
////				dismissProgressDialog();
////				
////				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_network), dialogListener);
////			}
////
////			@Override
////			public void onNoResponse() {
////				dismissProgressDialog();
////				
////				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_respond), dialogListener);
////			}
////
////			@Override
////			public void onSessionTimeOut() {
////				dismissProgressDialog();
////				
////				Dialogs.showDialog(HomeListActivity.this, getString(R.string.session_timeout), dialogListener);
////			}
////
////			@Override
////			public void onSuccess() {
////				dismissProgressDialog();
////				
////				Toast.makeText(HomeListActivity.this, getString(R.string.call_success), Toast.LENGTH_LONG).show();
////			}
////
////			@Override
////			public void onFail(int code, String msg) {
////				dismissProgressDialog();
////				
////				Dialogs.showDialog(HomeListActivity.this, getString(R.string.server_message) + msg, dialogListener);
////			}
////		});
//	}
		
	private void getTaxiDriverList(double latitude, double longitude) {
		showProgressDialog(this, R.string.loading);
		
		gateway.getTaxiDriverList(latitude, longitude, new GetDriverListListener() {

			@Override
			public void onNoNetwork() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_network), dialogListener3);
			}

			@Override
			public void onNoResponse() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_respond), dialogListener3);
			}

			@Override
			public void onSessionTimeOut() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.session_timeout), dialogListener3);
			}

			@Override
			public void onSuccess(List<Driver> drivers) {
				dismissProgressDialog();
				driverList.clear();
				
				driverList.addAll(drivers);
				mAdapter.notifyDataSetChanged();
			}

			@Override
			public void onFail(int code, String msg) {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.server_message) + msg, dialogListener3);
			}
		});
	}
	
	// ===========================================================
    // Methods (Overloading)
    // ===========================================================
	private void getTaxiDriverList(final double latitude, final double longitude, final int distance) {
		showProgressDialog(this, R.string.loading);
		
		gateway.getTaxiDriverList(latitude, longitude, new GetDriverListListener() {

			@Override
			public void onNoNetwork() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_network), dialogListener3);
			}

			@Override
			public void onNoResponse() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.no_respond), dialogListener3);
			}

			@Override
			public void onSessionTimeOut() {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.session_timeout), dialogListener3);
			}

			@Override
			public void onSuccess(List<Driver> drivers) {
				dismissProgressDialog();
				driverList.clear();
				
				final int size = drivers.size();
				final List<Driver> driverInDistance = new ArrayList<Driver> (size);
				
//				System.out.println(distance);
				for(int i = 0; i < drivers.size(); i++) {
					Driver driver = drivers.get(i);
					double driverLatitude = driver.getLatitude();
					double driverLongitude = driver.getLongitude();
//					System.out.println(Math.abs(distance(latitude, longitude, driverLatitude, driverLongitude)));
				
					if(Math.abs(distance(latitude, longitude, driverLatitude, driverLongitude)) < distance) {
						driverInDistance.add(driver);
					}
				}
				
				driverList.addAll(driverInDistance);
				mAdapter.notifyDataSetChanged();
			}

			@Override
			public void onFail(int code, String msg) {
				dismissProgressDialog();
				
				Dialogs.showDialog(HomeListActivity.this, getString(R.string.server_message) + msg, dialogListener3);
			}
		});
	}
		
	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
	private class AppDrawerListener implements DrawerLayout.DrawerListener {

		@Override
		public void onDrawerOpened(View drawerView) {
//			mOpenedDrawer = true;
		}

		@Override
		public void onDrawerClosed(View drawerView) {
//			mOpenedDrawer = false;
		}

		@Override
		public void onDrawerSlide(View drawerView, float slideOffset) {
		}

		@Override
		public void onDrawerStateChanged(int newState) {
		}
	}
	
	private DialogListener dialogListener = new DialogListener() {

		@Override
		public void onClickedOk() {
			Dialogs.dismiss();
		}

		@Override
		public void onClickedCancel() {
			Dialogs.dismiss();
		}
	};
		
//	private DialogListener dialogListener2 = new DialogListener() {
//	
//		@Override
//		public void onClickedOk() {
//			Dialogs.dismiss();
//			
//			requestCall();
//		}
//	
//		@Override
//		public void onClickedCancel() {
//			Dialogs.dismiss();
//		}
//	};
	
	private DialogListener dialogListener3 = new DialogListener() {

		@Override
		public void onClickedOk() {
			Dialogs.dismiss();
			
			finish();
		}

		@Override
		public void onClickedCancel() {
			// TODO Auto-generated method stub
		}
	};
	
	class DriverListAdapter extends ArrayAdapter<Driver> {

		private final LayoutInflater inflater;
		private final int resource;

		public DriverListAdapter(Context context, int resId, List<Driver> items) {
			super(context, resId, items);
			this.resource = resId;
			this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				convertView = inflater.inflate(resource, parent, false);
				holder = new ViewHolder();
				holder.name = (TextView) convertView.findViewById(R.id.driverlist_name_textview);
				holder.carNumber = (TextView) convertView.findViewById(R.id.driverlist_carnumber_textview);
				holder.company = (TextView) convertView.findViewById(R.id.driverlist_companyname_textview);
				//holder.company = (TextView) convertView.findViewById(R.id.driverlist_companyname_textview);
				holder.imgUrl = (ImageView) convertView.findViewById(R.id.driverlist_imageurl_imageview);
				holder.distance = (TextView) convertView.findViewById(R.id.driverlist_distance_textview);
				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}
			Driver item = getItem(position);
			holder.name.setText(item.getName());
			holder.carNumber.setText(item.getCarNumber());
			holder.company.setText(item.getCompany());
			LogControl.d(TAG, ""+item.getDistance());
			holder.distance.setText(item.getDistance()+"m");
			String imgUrlString = item.getImgUrl();
			if ("".equals(imgUrlString)) {
				holder.imgUrl.setBackgroundResource(R.drawable.driver_pic_bg);
			} else {
				application.getImageLoader().displayImage(imgUrlString, holder.imgUrl);
			}
			
			return convertView;
		}
		class ViewHolder {

			TextView name; // 기사 이름
			TextView company;	// 기사가 속한 회사이름
			TextView carNumber;	// 차량 번호
			ImageView imgUrl;	// 택시기사 사진 URL
			TextView distance;
		}
	}
	
	public double distance(double lat1, double lon1, double lat2, double lon2) {	
		double theta, dist;	
		theta = lon1 - lon2;	
		dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));	
		dist = Math.acos(dist);	
		dist = rad2deg(dist);	
		dist = dist * 60 * 1.1515; // statute miles. 단위는 기본 마일.	
		dist = dist * 1.609344;	
		return dist;
	}
	
	// 주어진 도(degree) 값을 라디언으로 변환
	private double deg2rad(double deg) {	
		return (double)(deg * Math.PI / (double)180d);
	}
	
	// 주어진 라디언(radian) 값을 도(degree) 값으로 변환
	private double rad2deg(double rad) {	
		return (double)(rad * (double)180d / Math.PI);
	}

}
